package com.iqik.base.alg;

import java.util.*;

public class BaseMap {

    /**
     * 对任意一个Map<String, Object>, 其 key 为 String,
     * 其 value 为 Map<String, Object> Object[] Number String 中的任意一种,
     * 显然叶子节点是 value 类型为 Number 或 String的节点,
     * 将 Map 转为多条字符串, 每条字符串表达其中一个叶子节点,
     * 比如:
     * {"a":{"b":["v",2,{"c":0}]},"d":[1,null,3]}
     * 将转化为以下这些字符串
     * a.b[0] = v
     * a.b[1] = 2
     * a.b[2].c = 0
     * d[0] = 1
     * d[1] = null
     * d[2] = 3
     *
     * @param map 上述的 map
     * @return 所有的字符串
     */
    public static Set<String> showMap(Map<String, Object> map) {
        //TODO your code goes here...
        if (map == null || map.size() ==0)
            return null;
        Set<String> sets = new HashSet<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String target = null;
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value == null) {
                target = String.format("%s = null", key);
            }
            if (value instanceof String) {
                target = String.format("%s = %s", key, value);
            }
            if (value instanceof ArrayList) {
                ArrayList<?> array = (ArrayList<?>) value;
                for (int i = 0; i < array.size(); i++) {
                    if (array.get(i) == null) {
                        target = String.format("%s[%d] = null", key, i);
                    }
                    if (array.get(i) instanceof String ){
                        target = String.format("%s[%d] = %s", key, i, array.get(i));
                    }
                    if (array.get(i) instanceof Integer) {
                        target = String.format("%s[%d] = %d", key, i, array.get(i));
                    }
                    if (array.get(i) instanceof Map) {
                        Set<String> strings = showMap((HashMap)array.get(i));
                        final int j = i;
                        strings.forEach((str) -> {
                            sets.add(String.format("%s[%d].%s", key, j, str));
                        });
                        continue;
                    }
                    sets.add(target);
                }
            }
            if (value instanceof Integer) {
                target = String.format("%s = %d", key, value);
            }
            if (value instanceof Map) {
                Set<String> strings = showMap((HashMap)value);
                strings.forEach((str) -> {
                    sets.add(String.format("%s.%s", key, str));
                });
                continue;
            }
            sets.add(target);
        }
        return sets;
    }


    public static void main(String[] args) {
        // {"a":{"b":["v",2,{"c":0}]},"d":[1,null,3]}
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> mapB = new HashMap<>();
        Map<String, Object> mapC = new HashMap<>();
        mapC.put("c", 0);
        ArrayList<Object> list = new ArrayList<>();
        list.add("v");
        list.add(2);
        list.add(mapC);
        mapB.put("b", list);
        map.put("a", mapB);
        Map<String, Object> mapD = new HashMap<>();
        ArrayList<Object> listD = new ArrayList<>();
        listD.add(1);
        listD.add(null);
        listD.add(3);
        map.put("d", listD);
//        map.put("b", 1);
//        HashMap<String, Object> mapSon = new HashMap<>();
//        mapSon.put("a1", "2");

//        map.put("pm", mapSon);
        Set<String> strings = showMap(map);
        strings.forEach(str -> {
            System.out.println(str);
        });
    }
}
